package ueb15;

import ueb15.Controller;
import ueb15.Node;
import ueb15.NodeImpl;
import ueb15.RedBlackTree;

/**
 * Allows us to notice changes.
 */
public class PaintableRedBlackTreeImpl extends RedBlackTreeImpl {

	private final Controller controler;

	public PaintableRedBlackTreeImpl(Controller controller) {
		super(); // Deleting this call would make it implicit
		this.controler = controller;
	}

	@Override
	public PaintableNodeImpl getRoot() {
		NodeImpl result = super.getRoot();
		if (result == null) {
			throw new IllegalStateException("Root cannot be null!");
		}
		if (result instanceof PaintableNodeImpl) {
			return (PaintableNodeImpl) result;
		}
		throw new IllegalStateException("Something went wrong. Please use 'RedBlackTree.createNode' instead of 'new NodeImpl'.");
	}

	@Override
	public PaintableNodeImpl insertValue(Object value) {
		NodeImpl result = super.insertValue(value);
		controler.updateGui();
		if (result == null) {
			throw new IllegalStateException(
					"Inserted node cannot be null. Return existing node if value is already contained.");
		}
		if (result instanceof PaintableNodeImpl) {
			return (PaintableNodeImpl) result;
		}
		throw new IllegalStateException("Something went wrong. Please use 'RedBlackTree.createNode' instead of 'new NodeImpl'.");
	}

	@Override
	protected PaintableNodeImpl createNode(NodeImpl nodeI) {
		if (nodeI == null) {
			throw new IllegalArgumentException("Parent cannot be null. Use createRoot instead.");
		}
		if (!(nodeI instanceof PaintableNodeImpl)) {
			throw new IllegalArgumentException("Given node was from a different tree!");
		}
		return new PaintableNodeImpl((PaintableNodeImpl) nodeI, this);
	}

	@Override
	protected PaintableNodeImpl createRoot() {
		return new PaintableNodeImpl(this);
	}

	protected Controller getControler() {
		return controler;
	}
}
